package com.itheima.travel.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.PageInterceptor;
import com.itheima.travel.interceptor.PrimaryKeyInterceptor;
import org.apache.ibatis.logging.log4j2.Log4j2Impl;
import org.apache.ibatis.plugin.Interceptor;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;
import java.util.Properties;

/**
 *
 */
// 声明配置类
@Configuration
// 读取外部配置文件
@PropertySource(value = "classpath:db.properties")
// 配置映射，并创建SqlSessionFactoryBean对象
@MapperScan(basePackages = {"com.itheima.travel.mapper","com.itheima.travel.mapperExt"},sqlSessionFactoryRef = "sqlSessionFactoryBean")
public class MybatisConfig {

    // 创建数据源
    @Value("${dataSource.driverClassName}")
    private String driverClassName;

    @Value("${dataSource.url}")
    private String url;

    @Value("${dataSource.username}")
    private String username;

    @Value("${dataSource.password}")
    private String password;

    @Value("${seq.workerId}")
    private String workerId;

    @Value("${seq.datacenterId}")
    private String datacenterId;

    /**
     * @Description 数据源配置
     * 细节：默认不指定名称使用当前方法名为bean的名称
     */
    @Bean("druidDataSource")
    public DruidDataSource dataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driverClassName);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        return dataSource;
    }

    // 配置事务管理器
    @Bean("transactionManager")
    public DataSourceTransactionManager transactionManager(@Qualifier("druidDataSource")DataSource dataSource){
        return new DataSourceTransactionManager(dataSource);
    }

    // 配置会话管理器
    @Bean("sqlSessionFactoryBean")
    public SqlSessionFactoryBean sqlSessionFactoryBean(@Qualifier("druidDataSource") DataSource dataSource){
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        // 指定数据源
        sqlSessionFactoryBean.setDataSource(dataSource);
        // 指定对应的别名
        sqlSessionFactoryBean.setTypeAliasesPackage("com.itheima.travel.pojo");
        // 指定高级配置，驼峰,是否返回主键,缓存,日志
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        configuration.setLogImpl(Log4j2Impl.class);
        // 插接,用于分页查询
        sqlSessionFactoryBean.setPlugins(new Interceptor[] {initPageInterceptor(),initPrimaryKeyInterceptor()});
        sqlSessionFactoryBean.setConfiguration(configuration);
        return sqlSessionFactoryBean;
    }

    @Bean
    public PageInterceptor initPageInterceptor(){
        PageInterceptor pageInterceptor = new PageInterceptor();
        // 为分分页拦截器准备配置参数
        Properties properties = new Properties();
        // 配置数据库方言
        properties.setProperty("helperDialect","mysql");
        // 该参数默认为false
        // 设置为true时,就可以使用当前页码+每页显示条数进行分页查询了
        properties.setProperty("offestAsPageNum","true");
        // 分页查询时需要查询满足条件的数据的总量
        properties.setProperty("rowBoundWithCount","true");
        pageInterceptor.setProperties(properties);
        return pageInterceptor;


    }

    /**
     * @Description 雪花算法支持
     */
    @Bean
    public SnowflakeIdWorker snowflakeIdWorker(){
        return new SnowflakeIdWorker(Long.valueOf(workerId),Long.valueOf(datacenterId));
    }

    /**
     * @Description 主键生成拦截
     */
    @Bean
    public PrimaryKeyInterceptor initPrimaryKeyInterceptor(){
        PrimaryKeyInterceptor primaryKeyInterceptor =  new PrimaryKeyInterceptor();
        Properties properties = new Properties();
        properties.setProperty("primaryKey", "id");
        primaryKeyInterceptor.setProperties(properties);
        primaryKeyInterceptor.setSnowflakeIdWorker(snowflakeIdWorker());
        return primaryKeyInterceptor;
    }
}
